#include <bits/stdc++.h>
using namespace std;
int T,n,m;
struct node{
    double d,v,a;
}c[100007];
double L,V,p[100007];
pair <double,double> mhy[1000007]; //first is end,second is begin,for easier to sort
double os(double x,double y,double z){
    if(z == 0.0) return -1;
    return x + (V*V -  y*y) / (2.0*z);
}
void solve(){
    scanf("%d%d%lf%lf",&n,&m,&L,&V);
    for(int i=0;i<n;i++) scanf("%lf%lf%lf",&c[i].d,&c[i].v,&c[i].a);
    for(int i=0;i<m;i++) scanf("%lf",&p[i]);
    //The first problem
    int cnt = 0;
    for(int i=0;i<n;i++){
        double K = os(c[i].d,c[i].v,c[i].a);
        if(c[i].a < 0){
            if(c[i].v < V) continue;
            if(lower_bound(p,p+m,c[i].d) - p != lower_bound(p,p+m,K) - p){
                mhy[cnt++] = make_pair(K - 1e-8,c[i].d);
            }
        }
        if(c[i].a > 0){
            if((upper_bound(p,p+m,K)) - p != m ){
                mhy[cnt++] = make_pair(L,K + 1e-8);
            }
        }
        if(c[i].a == 0.0){
            if(p[0] <= c[i].d && p[m-1] >= c[i].d && c[i].v > V){
                mhy[cnt++] = make_pair(L,c[i].d);
            }
        }
    }
    printf("%d ",cnt);
    //The second problem
    sort(mhy ,mhy + cnt);
    int lp = 0,ans = 1;
    while(p[lp] <= mhy[0].first && lp < m) lp++;
    lp--;
    for(int i=1;i<cnt;i++){
        if(mhy[i].second <= p[lp]) continue;
        while(p[lp] <= mhy[i].first && lp < m) lp++; //find the rightest P in smaller than mhy[i]
        lp--;
        ans++;
    }printf("%d\n",m - ans);
}
int main(){
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    scanf("%d",&T);
    while(T--) solve();
    return 0;
}
